/** * llmindex.io — GET /api/v1/leaderboard/:domain (per-domain ranking + sub-metrics) * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai * License: Proprietary — © Simon-Pierre Boucher, all rights reserved */ import { type NextRequest } from 'next/server'; import { isDomain } from '@llmindex/scoring'; import { getLeaderboard } from '@/lib/data'; import { apiError, apiJson } from '@/lib/api'; import { rateLimit } from '@/lib/rate-limit'; export const dynamic = 'force-dynamic'; export async function GET(req: NextRequest, { params }: { params: { domain: string } }) { const limited = await rateLimit(req); if (limited) return limited; if (!isDomain(params.domain)) return apiError(404, 'unknown_domain'); const search = req.nextUrl.searchParams; const limit = Math.min(200, Math.max(1, Number(search.get('limit') ?? 50))); const offset = Math.max(0, Number(search.get('offset') ?? 0)); const data = await getLeaderboard(params.domain, limit, offset); if (!data) return apiError(503, 'no_score_run_available'); return apiJson( { index_version: data.run.indexVersion, domain: params.domain, run: { id: data.run.id, kind: data.run.kind, status: data.run.status, created_at: data.run.createdAt, notes: data.run.notes, }, pagination: { limit, offset, count: data.entries.length }, entries: data.entries.map((e) => ({ rank: e.rank, model: e.slug, name: e.name, provider: e.provider, score: e.score, score_low: e.scoreLow, score_high: e.scoreHigh, sub_metrics: e.subMetrics, })), }, { cacheSeconds: 3600 }, ); }